package com.polimi.timer.business.weather.util;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;

public class WeatherUtil {
	private static final byte _5DAYS_FORECAST=5;
    private static final byte _16DAYS_FORECAST=16;   
    
    private static final String _5DAYS_URL = "http://api.openweathermap.org/data/2.5/forecast?q=";
    private static final String _16DAYS_URL = "http://api.openweathermap.org/data/2.5/forecast/daily?cnt=16&q=";    
    private static final String API_KEY="&APPID=63fff64ed5fbae839a4468016b0dfc89";
    
	public static JSONObject getForecast(String city, Date time) throws JSONException, IOException{
	    	String URL = null;
	    	JSONObject forecast=null;
	    	switch(WeatherUtil.ModeFetchingSelector(time)){
	    	case 5:
	    		URL=_5DAYS_URL+city+API_KEY;
	    		forecast=WeatherUtil.FiveDaysFetcher(time, URL);    		
	    		break;
	    	case 16:
	    		URL=_16DAYS_URL+city+API_KEY;
	    		forecast=WeatherUtil.SixteenDaysFetcher(time, URL);
	    		break;
	    	case 0:
	    		return null;
	    	} 
	    	return forecast;
    }
	/**
	 *  Select the right way to fetch data in relation of event data
	 */
	public static byte ModeFetchingSelector(Date time){
		Date date = new Date();
        long diff = time.getTime() - date.getTime();        
        long diffDays = diff / (24 * 60 * 60 * 1000);        
        if(diffDays<3){
        	return _5DAYS_FORECAST;
        }
        return _16DAYS_FORECAST;
	}
	/**
	 *  Fetch data through 5 day fetch call
	 */
	public static JSONObject FiveDaysFetcher(Date time, String URL) throws JSONException, IOException{
		JSONObject forecast=JsonReader.readJsonFromUrl(URL);
		String mappedDate=TimeMapping.mappedDate(time);
	   	for(int i=0;i<forecast.getJSONArray("list").length();i++){
	   		String jsonData=forecast.getJSONArray("list").getJSONObject(i).get("dt_txt").toString();
	   		if(mappedDate.equals(jsonData)){
	   			return forecast.getJSONArray("list").getJSONObject(i);
	   		}
	   	}    	
	   	return forecast;
	}
	/**
	 *  Fetch data through 16 day fetch call
	 */
	public static JSONObject SixteenDaysFetcher(Date time, String URL) throws JSONException, IOException{
		JSONObject Forecast=JsonReader.readJsonFromUrl(URL);
		Date date = new Date();
        long diff = time.getTime() - date.getTime();        
        long diffDays = diff / (24 * 60 * 60 * 1000);
        int day=(int)diffDays;
        if(day>16){
        	return null;
        }
        return (JSONObject) Forecast.getJSONArray("list").get(day);  	    	
	}
	/**
	 *  Find the first day where there's sunny
	 */
	public static Date getFirstClearDay(String city, Date date) throws ParseException, JSONException, IOException{		
		String jsonDate_json;
		Date jsondate;
		JSONObject forecast;
		String URL;
		
		URL=_5DAYS_URL+city+API_KEY;		
		forecast=FiveDaysFetcher(date, URL);
		for(int i=0;i<forecast.getJSONArray("list").length();i++){
	   		jsonDate_json=forecast.getJSONArray("list").getJSONObject(i).get("dt_txt").toString();	   		
   			jsondate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(jsonDate_json);
			if(jsondate.after(date)){
   				String jsonforecast=forecast.getJSONArray("list").getJSONObject(i).getJSONArray("weather").getJSONObject(0).getString("main");
   				if(jsonforecast.equals("Clear")){
   					return jsondate;
   				}
   			}				   			
	   	} 
		URL=_16DAYS_URL+city+API_KEY;
		forecast=SixteenDaysFetcher(date, URL);
		for(int i=5;i<forecast.getJSONArray("list").length();i++){
			jsonDate_json=forecast.getJSONArray("list").getJSONObject(i).getJSONArray("weather").getJSONObject(0).get("main").toString();
			jsondate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(jsonDate_json);
			if(jsondate.after(date)){
   				String jsonforecast=forecast.getJSONArray("list").getJSONObject(i).getJSONArray("weather").getJSONObject(0).getString("main");
   				if(jsonforecast.equals("Clear")){
   					return jsondate;
   				}
   			}
		}
		return null;
	}
}
